home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / Wipeout / source / dump.c < prev    next >
C/C++ Source or Header  |  2001-02-06  |  8KB  |  369 lines

  1. /*
  2.  * $Id: dump.c 1.15 1998/05/31 10:05:23 olsen Exp olsen $
  3.  *
  4.  * :ts=4
  5.  *
  6.  * Wipeout -- Traces and munges memory and detects memory trashing
  7.  *
  8.  * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  9.  * Public Domain
  10.  */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "global.h"
  14. #endif    /* _GLOBAL_H */
  15.  
  16. /******************************************************************************/
  17.  
  18. STATIC const STRPTR Separator = "---------------------------------------"
  19.                                 "---------------------------------------";
  20.  
  21. /******************************************************************************/
  22.  
  23. STATIC UBYTE
  24. GetHexChar(int v)
  25. {
  26.     UBYTE result;
  27.  
  28.     ASSERT(0 <= v && v <= 15);
  29.  
  30.     /* determine the ASCII character that belongs to a
  31.      * number (or nybble) in hexadecimal notation
  32.      */
  33.  
  34.     if(v <= 9)
  35.         result = '0' + v;
  36.     else
  37.         result = 'A' + (v - 10);
  38.  
  39.     return(result);
  40. }
  41.  
  42. /******************************************************************************/
  43.  
  44. VOID
  45. DumpWall(
  46.     const UBYTE *    wall,
  47.     int                wallSize,
  48.     UBYTE            fillChar)
  49. {
  50.     UBYTE line[80];
  51.     int i,j,k;
  52.  
  53.     /* dump the contents of a memory wall; we explicitely
  54.      * filter out those bytes that match the fill char.
  55.      */
  56.  
  57.     for(i = 0 ; i <= (wallSize / 20) ; i++)
  58.     {
  59.         memset(line,' ',sizeof(line)-1);
  60.         line[sizeof(line)-1] = '\0';
  61.  
  62.         for(j = 0 ; j < 20 ; j++)
  63.         {
  64.             k = i * 20 + j;
  65.  
  66.             if(k < wallSize)
  67.             {
  68.                 UBYTE c = wall[k];
  69.  
  70.                 /* don't show the fill character */
  71.                 if(c == fillChar)
  72.                 {
  73.                     line[j * 2]    = '.';
  74.                     line[j * 2 +1] = '.';
  75.  
  76.                     line[41 + j] = '.';
  77.                 }
  78.                 else
  79.                 {
  80.                     /* fill in the trash character and
  81.                      * also put in an ASCII representation
  82.                      * of its code.
  83.                      */
  84.                     line[j * 2]    = GetHexChar(c >> 4);
  85.                     line[j * 2 +1] = GetHexChar(c & 15);
  86.  
  87.                     if(c <= ' ' || (c >= 127 && c <= 160))
  88.                         c = '.';
  89.  
  90.                     line[41 + j] = c;
  91.                 }
  92.             }
  93.             else
  94.             {
  95.                 /* fill the remainder of the line */
  96.                 while(j < 20)
  97.                 {
  98.                     line[j * 2]    = '.';
  99.                     line[j * 2 +1] = '.';
  100.  
  101.                     line[41 + j] = '.';
  102.  
  103.                     j++;
  104.                 }
  105.  
  106.                 break;
  107.             }
  108.         }
  109.  
  110.         DPrintf("%08lx: %s\n",&wall[i * 20],line);
  111.     }
  112. }
  113.  
  114. /******************************************************************************/
  115.  
  116. STATIC VOID
  117. DumpRange(
  118.     const STRPTR    header,
  119.     const ULONG *    range,
  120.     int                numRangeLongs,
  121.     BOOL            check)
  122. {
  123.     int i;
  124.  
  125.     /* dump and check a range of long words. */
  126.     for(i = 0 ; i < numRangeLongs ; i++)
  127.     {
  128.         if((i % 8) == 0)
  129.         {
  130.             DPrintf("%s:",header);
  131.         }
  132.  
  133.         DPrintf(" %08lx",range[i]);
  134.  
  135.         if((i % 8) == 7)
  136.         {
  137.             DPrintf("\n");
  138.  
  139.             /* check every long word processed so far? */
  140.             if(check)
  141.             {
  142.                 ULONG segment;
  143.                 ULONG offset;
  144.                 int j;
  145.  
  146.                 for(j = i - 7 ; j <= i ; j++)
  147.                 {
  148.                     if(FindAddress(range[j],sizeof(GlobalNameBuffer),GlobalNameBuffer,&segment,&offset))
  149.                     {
  150.                         DPrintf("----> %08lx - \"%s\" Hunk %04lx Offset %08lx\n",
  151.                             range[j],GlobalNameBuffer,segment,offset);
  152.                     }
  153.                 }
  154.             }
  155.         }
  156.     }
  157. }
  158.  
  159. /******************************************************************************/
  160.  
  161. VOID
  162. VoiceComplaint(
  163.     ULONG *                    stackFrame,
  164.     struct TrackHeader *    th,
  165.     const STRPTR            format,
  166.                             ...)
  167. {
  168.     ULONG segment;
  169.     ULONG offset;
  170.  
  171.     /* show the hit header, if there is one */
  172.     if(format != NULL)
  173.     {
  174.         va_list varArgs;
  175.         struct timeval tv;
  176.  
  177.         GetSysTime(&tv);
  178.         ConvertTimeAndDate(&tv,GlobalDateTimeBuffer);
  179.         DPrintf("\n\aWIPEOUT HIT\n%s\n",GlobalDateTimeBuffer);
  180.  
  181.         /* print the message to follow it */
  182.         va_start(varArgs,format);
  183.         DVPrintf(format,varArgs);
  184.         va_end(varArgs);
  185.     }
  186.  
  187.     /* show the stack frame, if there is one; this also includes
  188.      * a register dump.
  189.      */
  190.     if(stackFrame != NULL)
  191.     {
  192.         struct Process * thisProcess;
  193.  
  194.         DumpRange("Data",stackFrame,8,DRegCheck);
  195.         DumpRange("Addr",&stackFrame[8],8,ARegCheck);
  196.         DumpRange("Stck",&stackFrame[17],8 * StackLines,StackCheck);
  197.  
  198.         /* show the name of the currently active process/task/whatever. */
  199.         thisProcess = (struct Process *)FindTask(NULL);
  200.         DPrintf("Name: \"%s\"",thisProcess->pr_Task.tc_Node.ln_Name);
  201.     
  202.         if(thisProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS)
  203.         {
  204.             struct CommandLineInterface * cli;
  205.     
  206.             cli = BADDR(thisProcess->pr_CLI);
  207.             if(cli != NULL)
  208.             {
  209.                 if(cli->cli_CommandName != NULL)
  210.                     DPrintf("  CLI: \"%b\"",cli->cli_CommandName);
  211.             }
  212.         }
  213.  
  214.         /* if possible, show the hunk offset of the caller return
  215.          * address; for FreeMem() this would be the next instruction
  216.          * after the FreeMem() call.
  217.          */
  218.         if(FindAddress(stackFrame[16],sizeof(GlobalNameBuffer),GlobalNameBuffer,&segment,&offset))
  219.         {
  220.             DPrintf("  \"%s\" Hunk %04lx Offset %08lx",GlobalNameBuffer,segment,offset);
  221.         }
  222.  
  223.         DPrintf("\n");
  224.     }
  225.  
  226.     /* show the data associated with the memory tracking
  227.      * header, if there is one.
  228.      */
  229.     if(th != NULL)
  230.     {
  231.         BOOL showCreator;
  232.         UBYTE * mem;
  233.         STRPTR type;
  234.  
  235.         if(format != NULL || stackFrame != NULL)
  236.         {
  237.             DPrintf("%s\n",Separator);
  238.         }
  239.  
  240.         switch(th->th_Type)
  241.         {
  242.             case ALLOCATIONTYPE_AllocMem:
  243.  
  244.                 type = "AllocMem(%ld,...)";
  245.                 break;
  246.  
  247.             case ALLOCATIONTYPE_AllocVec:
  248.  
  249.                 type = "AllocVec(%ld,...)";
  250.                 break;
  251.  
  252.             case ALLOCATIONTYPE_AllocPooled:
  253.  
  254.                 type = "AllocPooled(...,%ld)";
  255.                 break;
  256.  
  257.             default:
  258.  
  259.                 type = "";
  260.                 break;
  261.         }
  262.  
  263.         ConvertTimeAndDate(&th->th_Time,GlobalDateTimeBuffer);
  264.  
  265.         mem = (UBYTE *)(th + 1);
  266.         mem += PreWallSize;
  267.  
  268.         /* show type, size and place of the allocation; AllocVec()
  269.          * allocations are special in that the memory body is actually
  270.          * following a size long word.
  271.          */
  272.         if(th->th_Type == ALLOCATIONTYPE_AllocVec)
  273.         {
  274.             DPrintf("0x%08lx = ",mem + sizeof(ULONG));
  275.             DPrintf(type,th->th_Size - sizeof(ULONG));
  276.         }
  277.         else
  278.         {
  279.             DPrintf("0x%08lx = ",mem);
  280.             DPrintf(type,th->th_Size);
  281.         }
  282.  
  283.         DPrintf("\n");
  284.  
  285.         /* show information on the time and the task/process/whatever
  286.          * that created the allocation.
  287.          */
  288.         DPrintf("Created on %s\n",GlobalDateTimeBuffer);
  289.  
  290.         DPrintf("        by task 0x%08lx",th->th_Owner);
  291.  
  292.         showCreator = TRUE;
  293.  
  294.         if(th->th_NameTagLen > 0)
  295.         {
  296.             STRPTR taskNameBuffer;
  297.             STRPTR programNameBuffer;
  298.  
  299.             if(GetNameTagData(th,th->th_NameTagLen,&programNameBuffer,&segment,&offset,&taskNameBuffer))
  300.             {
  301.                 DPrintf(", %s \"%s\"\n",GetTaskTypeName(th->th_OwnerType),taskNameBuffer);
  302.  
  303.                 DPrintf("        at \"%s\" Hunk %04lx Offset %08lx",programNameBuffer,segment,offset);
  304.  
  305.                 showCreator = FALSE;
  306.             }
  307.         }
  308.  
  309.         DPrintf("\n");
  310.  
  311.         if(showCreator || th->th_ShowPC)
  312.         {
  313.             if(FindAddress(th->th_PC,sizeof(GlobalNameBuffer),GlobalNameBuffer,&segment,&offset))
  314.                 DPrintf("        at \"%s\" Hunk %04lx Offset %08lx\n",GlobalNameBuffer,segment,offset);
  315.         }
  316.  
  317.         DPrintf("%s\n",Separator);
  318.     }
  319. }
  320.  
  321. /******************************************************************************/
  322.  
  323. VOID
  324. DumpPoolOwner(const struct PoolHeader * ph)
  325. {
  326.     BOOL showCreator;
  327.     ULONG segment;
  328.     ULONG offset;
  329.  
  330.     /* show information on the creator of a memory pool. */
  331.     ConvertTimeAndDate(&ph->ph_Time,GlobalDateTimeBuffer);
  332.  
  333.     DPrintf("%s\n",Separator);
  334.  
  335.     DPrintf("0x%08lx = CreatePool(...)\n",ph->ph_PoolHeader);
  336.     DPrintf("Created on %s\n",GlobalDateTimeBuffer);
  337.  
  338.     DPrintf("        by task 0x%08lx",ph->ph_Owner);
  339.  
  340.     showCreator = TRUE;
  341.  
  342.     if(ph->ph_NameTagLen > 0)
  343.     {
  344.         STRPTR taskNameBuffer;
  345.         STRPTR programNameBuffer;
  346.  
  347.         if(GetNameTagData((APTR)ph,ph->ph_NameTagLen,&programNameBuffer,&segment,&offset,&taskNameBuffer))
  348.         {
  349.             DPrintf(", %s \"%s\"\n",GetTaskTypeName(ph->ph_OwnerType),taskNameBuffer);
  350.  
  351.             DPrintf("        at \"%s\" Hunk %04lx Offset %08lx",programNameBuffer,segment,offset);
  352.  
  353.             showCreator = FALSE;
  354.         }
  355.     }
  356.  
  357.     DPrintf("\n");
  358.  
  359.     if(showCreator)
  360.     {
  361.         if(FindAddress(ph->ph_PC,sizeof(GlobalNameBuffer),GlobalNameBuffer,&segment,&offset))
  362.         {
  363.             DPrintf("        at \"%s\" Hunk %04lx Offset %08lx\n",GlobalNameBuffer,segment,offset);
  364.         }
  365.     }
  366.  
  367.     DPrintf("%s\n",Separator);
  368. }
  369.